package com.xzcs.util.redis;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisException;

import java.util.*;

/**
 * @desc:
 * @author: chang
 * @date: 2017/5/23
 */
public class JedisUtils {
    private static Logger logger = LoggerFactory.getLogger(JedisUtils.class);

    private JedisPool jedisPool;
    public JedisPool getJedisPool() {
        return jedisPool;
    }
    public void setJedisPool(JedisPool jedisPool) {
        this.jedisPool = jedisPool;
    }

    public String select(int index){
        Jedis jedis = null;
        String select = "";
        try {
            jedis = jedisPool.getResource();
            select = jedis.select(index);
        } catch (Exception e) {
            logger.error("select", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return select;
    }

    /**
     * redis的List集合，向key这个list添加元素
     */
    public long rpush(String key, String string) {
        Jedis jedis = null;
        long ret = 0;
        try {
            jedis = jedisPool.getResource();
            ret = jedis.rpush(key, string);
        } catch (Exception e) {
            logger.error("rpush", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return ret;
    }
    /**
     * 获取key这个List，从第几个元素到第几个元素 LRANGE key start
     * stop返回列表key中指定区间内的元素，区间以偏移量start和stop指定。
     * 下标(index)参数start和stop都以0为底，也就是说，以0表示列表的第一个元素，以1表示列表的第二个元素，以此类推。
     * 也可以使用负数下标，以-1表示列表的最后一个元素，-2表示列表的倒数第二个元素，以此类推。
     */
    public List<String> lrange(String key, long start, long end) {
        Jedis jedis = null;
        List<String> ret = new ArrayList<String>();
        try {
            jedis = jedisPool.getResource();
            ret = jedis.lrange(key, start, end);
        } catch (Exception e) {
            logger.error("lrange", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return ret;
    }
    /**
     * 将哈希表key中的域field的值设为value。
     */
    public void hset(String key, String field, String value) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.hset(key, field, value);
        } catch (Exception e) {
            logger.error("hset", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
    /**
     * 向key赋值
     */
    public void set(String key, String value) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.set(key, value);
        } catch (Exception e) {
            logger.error("set", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
    /**
     * 向key赋值
     */
    public void set(byte[] key, byte[] value) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.set(key, value);
        } catch (Exception e) {
            logger.error("set", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
    /**
     * 获取key的值
     */
    public String get(String key) {
        Jedis jedis = null;
        String value = "";
        try {
            jedis = jedisPool.getResource();
            value = jedis.get(key);
        } catch (Exception e) {
            logger.error("get", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return value;
    }
    /**
     * 获取key的值
     */
    public byte[] get(byte[] key) {
        Jedis jedis = null;
        byte[] value = new byte[]{};
        try {
            jedis = jedisPool.getResource();
            value = jedis.get(key);
        } catch (Exception e) {
            logger.error("get", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return value;
    }
    /**
     * 将多个field - value(域-值)对设置到哈希表key中。
     */
    public void hmset(String key, Map<String, String> map) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.hmset(key, map);
        } catch (Exception e) {
            logger.error("hmset", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
    /**
     * 给key赋值，并生命周期设置为seconds
     */
    public void setex(String key, int seconds, String value) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.setex(key, seconds, value);
        } catch (Exception e) {
            logger.error("setex", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
    /**
     * 给key赋值，并生命周期设置为seconds
     */
    public void setex(byte[] key, int seconds, byte[] value) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.setex(key, seconds, value);
        } catch (Exception e) {
            logger.error("setex", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
    /**
     * 为给定key设置生命周期
     */
    public void expire(String key, int seconds) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.expire(key, seconds);
        } catch (Exception e) {
            logger.error("expire", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
    /**
     * 为给定key设置生命周期
     */
    public void expire(byte[] key, int seconds) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.expire(key, seconds);
        } catch (Exception e) {
            logger.error("expire", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
    /**
     * 检查key是否存在
     */
    public boolean exists(String key) {
        Jedis jedis = null;
        boolean bool = false;
        try {
            jedis = jedisPool.getResource();
            bool = jedis.exists(key);
        } catch (Exception e) {
            logger.error("exists", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return bool;
    }
    /**
     * 检查key是否存在
     */
    public boolean exists(byte[] key) {
        Jedis jedis = null;
        boolean bool = false;
        try {
            jedis = jedisPool.getResource();
            Set<byte[]> hashSet = jedis.keys(key);
            jedisPool.returnResource(jedis);
            if (null != hashSet && hashSet.size() >0 ){
                bool = true;
            }else{
                bool = false;
            }
        } catch (Exception e) {
            logger.error("exists", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return bool;
    }
    /**
     * 返回key值的类型 none(key不存在),string(字符串),list(列表),set(集合),zset(有序集),hash(哈希表)
     */
    public String type(String key) {
        Jedis jedis = null;
        String type = "";
        try {
            jedis = jedisPool.getResource();
            type = jedis.type(key);
        } catch (Exception e) {
            logger.error("type", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return type;
    }
    /**
     * 从哈希表key中获取field的value
     */
    public String hget(String key, String field) {
        Jedis jedis = null;
        String value = "";
        try {
            jedis = jedisPool.getResource();
            value = jedis.hget(key, field);
        } catch (Exception e) {
            logger.error("hget", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return value;
    }
    /**
     * 返回哈希表key中，所有的域和值
     */
    public Map<String, String> hgetAll(String key) {
        Jedis jedis = null;
        Map<String, String> map = new HashMap<String, String>();
        try {
            jedis = jedisPool.getResource();
            map = jedis.hgetAll(key);
        } catch (Exception e) {
            logger.error("hgetAll", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return map;
    }
    /**
     * 返回哈希表key中，所有的域和值
     */
    public Set<?> smembers(String key) {
        Jedis jedis = null;
        Set<?> set = new HashSet();
        try {
            jedis = jedisPool.getResource();
            set = jedis.smembers(key);
        } catch (Exception e) {
            logger.error("smembers", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return set;
    }
    /**
     * 返回匹配的 keys 列表
     */
    public Set<byte[]> keys(String pattern) {
        Jedis jedis = null;
        Set<byte[]> keys = new HashSet<byte[]>();
        try {
            jedis = jedisPool.getResource();
            keys = jedis.keys(pattern.getBytes());
        } catch (Exception e) {
            logger.error("keys", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return keys;
    }
    /**
     * 移除set集合中的member元素
     */
    public void delSetObj(String key, String field) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.srem(key, field);
        } catch (Exception e) {
            logger.error("delSetObj", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
    /**
     * 删除元素
     */
    public void del(byte[] key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.del(key);
        } catch (Exception e) {
            logger.error("del", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
    /**
     * 判断member元素是否是集合key的成员。是（true），否则（false）
     */
    public boolean isNotField(String key, String field) {
        Jedis jedis = null;
        boolean bool = false;
        try {
            jedis = jedisPool.getResource();
            bool = jedis.sismember(key, field);
        } catch (Exception e) {
            logger.error("isNotField", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return bool;
    }
    /**
     * 如果key已经存在并且是一个字符串，将value追加到key原来的值之后
     */
    public void append(String key, String value) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.append(key, value);
        } catch (Exception e) {
            logger.error("append", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
    /**
     * 返回当前redis库所存储数据的大小
     */
    public Long dbSize() {
        Long dbSize = 0L;
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.dbSize();
        } catch (Exception e) {
            logger.error("dbSize", e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return dbSize;
    }
    /**
     * 清空当前的redis库
     */
    public void flushDB() {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.flushDB();
            jedisPool.returnResource(jedis);
        } catch (Exception e) {
            logger.error("flushDB", e);
            if (jedis != null) {
                jedisPool.returnBrokenResource(jedis);
            }
            throw new JedisException(e);
        }
    }
    /**
     * 关闭 Redis
     */
    public void destory() {
        jedisPool.destroy();
    }
}
